home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / ASTPrintExpr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-27  |  6.2 KB  |  192 lines  |  [TEXT/KAHL]

  1. /* ASTPrintExpr.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "ASTPrintExpr.h"
  31. #include "TrashTracker.h"
  32. #include "Memory.h"
  33. #include "ASTExpression.h"
  34. #include "PromotableTypeCheck.h"
  35.  
  36.  
  37. struct ASTPrintExprRec
  38.     {
  39.         ASTExpressionRec*        Value;
  40.         long                                LineNumber;
  41.         DataTypes                        ExpressionType;
  42.     };
  43.  
  44.  
  45. /* create a new AST expression print */
  46. ASTPrintExprRec*        NewPrintExpr(struct ASTExpressionRec* Expression,
  47.                                             struct TrashTrackRec* TrashTracker, long LineNumber)
  48.     {
  49.         ASTPrintExprRec*    PrintExpr;
  50.  
  51.         CheckPtrExistence(Expression);
  52.         PrintExpr = (ASTPrintExprRec*)AllocTrackedBlock(sizeof(ASTPrintExprRec),TrashTracker);
  53.         if (PrintExpr == NIL)
  54.             {
  55.                 return NIL;
  56.             }
  57.         SetTag(PrintExpr,"ASTPrintExprRec");
  58.  
  59.         PrintExpr->Value = Expression;
  60.         PrintExpr->LineNumber = LineNumber;
  61.  
  62.         return PrintExpr;
  63.     }
  64.  
  65.  
  66. /* type check the expr print node.  this returns eCompileNoError if */
  67. /* everything is ok, and the appropriate type in *ResultingDataType. */
  68. CompileErrors                TypeCheckPrintExpr(DataTypes* ResultingDataType,
  69.                                             ASTPrintExprRec* PrintExpr, long* ErrorLineNumber,
  70.                                             struct TrashTrackRec* TrashTracker)
  71.     {
  72.         CompileErrors            Error;
  73.  
  74.         CheckPtrExistence(PrintExpr);
  75.         CheckPtrExistence(TrashTracker);
  76.  
  77.         Error = TypeCheckExpression(&(PrintExpr->ExpressionType),PrintExpr->Value,
  78.             ErrorLineNumber,TrashTracker);
  79.         if (Error != eCompileNoError)
  80.             {
  81.                 return Error;
  82.             }
  83.  
  84.         switch (PrintExpr->ExpressionType)
  85.             {
  86.                 default:
  87.                     EXECUTE(PRERR(ForceAbort,"TypeCheckPrintExpr:  unknown expression type"));
  88.                     break;
  89.                 case eBoolean:
  90.                     break;
  91.                 case eDouble:
  92.                 case eInteger:
  93.                 case eFloat:
  94.                 case eFixed:
  95.                     if (!CanRightBeMadeToMatchLeft(eDouble,PrintExpr->ExpressionType))
  96.                         {
  97.                             *ErrorLineNumber = PrintExpr->LineNumber;
  98.                             return eCompileOperandMustBeDouble;
  99.                         }
  100.                     if (MustRightBePromotedToLeft(eDouble,PrintExpr->ExpressionType))
  101.                         {
  102.                             ASTExpressionRec*        PromotedOperand;
  103.  
  104.                             /* we must promote the right operand to become the left operand type */
  105.                             PromotedOperand = PromoteTheExpression(PrintExpr->ExpressionType/*orig*/,
  106.                                 eDouble/*desired*/,PrintExpr->Value,PrintExpr->LineNumber,TrashTracker);
  107.                             if (PromotedOperand == NIL)
  108.                                 {
  109.                                     *ErrorLineNumber = PrintExpr->LineNumber;
  110.                                     return eCompileOutOfMemory;
  111.                                 }
  112.                             PrintExpr->Value = PromotedOperand;
  113.                             /* sanity check */
  114.                             Error = TypeCheckExpression(&(PrintExpr->ExpressionType)/*obtain new type*/,
  115.                                 PrintExpr->Value,ErrorLineNumber,TrashTracker);
  116.                             ERROR((Error != eCompileNoError),PRERR(ForceAbort,
  117.                                 "TypeCheckPrintExpr:  type promotion caused failure"));
  118.                             ERROR(eDouble != PrintExpr->ExpressionType,PRERR(ForceAbort,
  119.                                 "TypeCheckPrintExpr:  after type promotion, types are no"
  120.                                 " longer the same"));
  121.                         }
  122.                     break;
  123.                 case eArrayOfBoolean:
  124.                 case eArrayOfInteger:
  125.                 case eArrayOfFloat:
  126.                 case eArrayOfDouble:
  127.                 case eArrayOfFixed:
  128.                     *ErrorLineNumber = PrintExpr->LineNumber;
  129.                     return eCompileOperandsMustBeScalar;
  130.             }
  131.  
  132.         *ResultingDataType = eBoolean;
  133.         return eCompileNoError;
  134.     }
  135.  
  136.  
  137. /* generate code for an expr print.  returns True if successful, or False if it fails. */
  138. MyBoolean                        CodeGenPrintExpr(struct PcodeRec* FuncCode,
  139.                                             long* StackDepthParam, ASTPrintExprRec* PrintExpr)
  140.     {
  141.         long                            StackDepth;
  142.  
  143.         CheckPtrExistence(FuncCode);
  144.         CheckPtrExistence(PrintExpr);
  145.         StackDepth = *StackDepthParam;
  146.  
  147.         /* evaluate the operand */
  148.         if (!CodeGenExpression(FuncCode,&StackDepth,PrintExpr->Value))
  149.             {
  150.                 return False;
  151.             }
  152.         ERROR(StackDepth != *StackDepthParam + 1,PRERR(ForceAbort,
  153.             "CodeGenPrintExpr:  stack depth error evaluating operand"));
  154.  
  155.         /* generate operation */
  156.         switch (PrintExpr->ExpressionType)
  157.             {
  158.                 default:
  159.                     EXECUTE(PRERR(ForceAbort,"CodeGenPrintExpr:  unknown type"));
  160.                     break;
  161.                 case eBoolean:
  162.                     if (!AddPcodeInstruction(FuncCode,epPrintBool,NIL))
  163.                         {
  164.                             return False;
  165.                         }
  166.                     break;
  167.                 case eDouble:
  168.                     if (!AddPcodeInstruction(FuncCode,epPrintDouble,NIL))
  169.                         {
  170.                             return False;
  171.                         }
  172.                     break;
  173.             }
  174.         StackDepth -= 1;
  175.  
  176.         /* return value */
  177.         if (!AddPcodeInstruction(FuncCode,epLoadImmediateInteger,NIL))
  178.             {
  179.                 return False;
  180.             }
  181.         if (!AddPcodeOperandInteger(FuncCode,True))
  182.             {
  183.                 return False;
  184.             }
  185.         StackDepth += 1;
  186.         ERROR(StackDepth != *StackDepthParam + 1,PRERR(ForceAbort,
  187.             "CodeGenPrintExpr:  stack depth error after pushing return value"));
  188.  
  189.         *StackDepthParam = StackDepth;
  190.         return True;
  191.     }
  192.